package com.music.players;

import com.music.MusicManager;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;

public class WavPlayer implements IPlayer {

    private volatile int status = STOPPED;
    public static final int STOPPED = 0;
    public static final int PLAYING = 1;
    private volatile int newPosition = -1;
    private Clip clip;
    private boolean shouldStop = false;

    public WavPlayer(String fileName) throws IOException {
        try {
            clip = AudioSystem.getClip();
            clip.open(AudioSystem.getAudioInputStream(new File(fileName)));
        } catch (LineUnavailableException | UnsupportedAudioFileException ex) {
            ex.printStackTrace();
        }
    }

    @Override
    public void close() {
        clip.close();
    }

    @Override
    public void play() {
        if (MusicManager.getInstance().isMuted()) {
            return;
        }
        synchronized (this) {
            if (status == STOPPED) {
                Thread thread = new Thread() {
                    @Override
                    public void run() {
                        try {
                            clip.start();
                            status = PLAYING;
                            while (clip.isRunning()) {
                                if (shouldStop) {
                                    shouldStop = false;
                                    clip.stop();
                                } else if (newPosition != -1) {
                                    clip.stop();
                                    clip.setFramePosition(0);
                                    newPosition = -1;
                                    clip.start();
                                } else {
                                    Thread.sleep(10);
                                }
                            }
                            if (clip.isOpen()) {
                                clip.setMicrosecondPosition(0);
                            }
                            status = STOPPED;
                        } catch (Exception exc) {
                            exc.printStackTrace(System.out);
                        }
                    }
                };
                thread.start();
            } else {
                newPosition = 0;
            }
        }
    }

    @Override
    public void stop() {
        synchronized (this) {
            shouldStop = true;
        }
    }

    @Override
    public PlayerStatus getStatus() {
        return status == PLAYING ? PlayerStatus.Play : PlayerStatus.Stop;
    }

    @Override
    public void mute(boolean shouldMute) {

    }
}
